package main

import (
	"context"
	"fmt"
	"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
	"golang.org/x/net/trace"
	"google.golang.org/grpc"
	"grpc_learn/gen-proto/user"
	"log"
	"log/slog"
	"net"
	"net/http"
)

const address = "127.0.0.1:50001"
const traceAddress = "127.0.0.1:50051"
const httpAddress = "127.0.0.1:50002"

func init() {
	// 启用跟踪
	grpc.EnableTracing = true
}

func main() {
	// 创建grpc服务端
	server := grpc.NewServer()
	user.RegisterUserServer(server, UserServer{})
	// 创建指定的tcp端口监听
	listen, err := net.Listen("tcp", address)
	if err != nil {
		// 端口占用
		log.Fatalln("端口占用!!!")
	}
	startTrace()
	go func() {
		// 启动服务
		err = server.Serve(listen)
		if err != nil {
			log.Fatalln("启动gRPC服务错误!!!")
		}
	}()
	slog.Info("user grpc service listing port 50001")
	// 开启grpc-gateway
	// 创建客户端连接（将接收到的http请求转换为grpc客户端调用）
	conn, err := grpc.Dial(
		fmt.Sprintf(address),
		grpc.WithInsecure(),
	)
	if err != nil {
		log.Fatalln("Failed to dial server:", err)
	}
	gatewayMux := runtime.NewServeMux()
	// Register User
	err = user.RegisterUserHandler(context.Background(), gatewayMux, conn)
	if err != nil {
		log.Fatalln("Failed to register gateway:", err)
	}
	gwServer := &http.Server{
		Addr:    httpAddress,
		Handler: gatewayMux,
	}

	log.Println("Serving gRPC-Gateway on " + httpAddress)
	log.Fatalln(gwServer.ListenAndServe())
}

type UserServer struct {
	user.UnimplementedUserServer
}

func (UserServer) GetUser(ctx context.Context, req *user.UserRequest) (*user.UserResponse, error) {
	return &user.UserResponse{Code: 200, Users: []*user.UserModel{
		{Id: 1, Name: req.GetName(), Age: 20},
	}}, nil
}
func (UserServer) PostUser(ctx context.Context, req *user.PostUserReq) (*user.PostUserRes, error) {
	return &user.PostUserRes{
		Code: 200,
		Msg:  "操作成功",
	}, nil
}
func (UserServer) mustEmbedUnimplementedUserServer() {}

func startTrace() {
	trace.AuthRequest = func(req *http.Request) (any, sensitive bool) {
		return true, true
	}
	go http.ListenAndServe(traceAddress, nil)
	slog.Info(fmt.Sprintf("Trace listen on %s", traceAddress))
}
